package com.cloud.music.config.proxy;

import com.cloud.music.annotation.MusicService;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;

import java.util.Arrays;
import java.util.Set;

@Slf4j
public class MusicServiceClassPathScanner extends ClassPathBeanDefinitionScanner {

    public MusicServiceClassPathScanner(BeanDefinitionRegistry registry) {
        // 不使用默认的过滤器
        super(registry, false);
    }

    @Override
    protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
        // 增加过滤，为接口类，MusicService
        return beanDefinition.getMetadata().isInterface() && // 接口类
                beanDefinition.getMetadata().isIndependent() &&  // 判断是否是独立的类
                beanDefinition.getMetadata().hasAnnotation(MusicService.class.getName());
    }

    @Override
    protected boolean checkCandidate(@NotNull String beanName, @NotNull BeanDefinition beanDefinition) {
        if (super.checkCandidate(beanName, beanDefinition)) {
            return true;
        } else {
            log.info("Skipping MusicServiceFactoryBean with name '" + beanName + "' and '" + beanDefinition.getBeanClassName() + "' MusicServiceInterface. Bean already defined with the same name!");
            return false;
        }
    }

    @NotNull
    @Override
    public Set<BeanDefinitionHolder> doScan(@NotNull String... basePackages) {
        // spring默认不会扫描接口，此处设置为true，不做过滤
        this.addIncludeFilter((metadataReader, metadataReaderFactory) -> true);
        // 扫描指定包路径下的类
        Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);
        // 如果没有扫描到任何类，打印警告
        if (beanDefinitions.isEmpty()) {
            log.warn("No MusicServiceInterface was found in" + Arrays.toString(basePackages) + "package. Please check your configuration.");
        } else {
            this.processBeanDefinitions(beanDefinitions);
        }
        return beanDefinitions;
    }

    private void processBeanDefinitions(Set<BeanDefinitionHolder> beanDefinitions) {
        beanDefinitions.forEach((BeanDefinitionHolder holder) -> {
            GenericBeanDefinition definition = (GenericBeanDefinition) holder.getBeanDefinition();
            String beanClassName = definition.getBeanClassName();
            // 设置MusicServiceFactoryBean构造方法参数
            definition.getConstructorArgumentValues().addGenericArgumentValue(beanClassName);
            definition.setBeanClass(MusicServiceFactoryBean.class);
            definition.setAutowireMode(GenericBeanDefinition.AUTOWIRE_BY_TYPE);
        });
    }
}
